/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pencarian;
import java.util.ArrayList;
/**
 *
 * @author hans
 */
public class BFS {
    private Track currSolution; //tempat menyimpan urutan jalur
    private ArrayList<Coordinat> CoordinatSolution; //hasil yang berupa susunan koordinat
    private Coordinat currPoint; //penunjuk lokasi truk sekarang
    private int maxWeight; //jumlah barang maksimum yang bisa ditampung truk
    private int currWeight; //jumlah barang pada truk saat ini
    private int currItem; //index barang yang sedang dicari saat ini
    private ArrayList<Integer> currListItem; //list barang yang perlu dicari (-999 jika target adalah P)
    private MapTranslator Situation; //menggambarkan abstraksi map, jika ingin mendapatkan matriks map, gunakan Situation.getmap()
    private ArrayList<BFSQueue> Queue; //antrian BFS
    private ArrayList<Coordinat> visitedArray; //daftar node yg sudah visited
    public BFS(Input inputan,String namafile){
        currSolution = new Track("");
        maxWeight = inputan.getmaxWeight();
        currWeight = 0;
        currItem = 0;
        currListItem = new ArrayList<Integer>(inputan.getlistbarang());
        Situation = new MapTranslator(namafile);
        currPoint = new Coordinat(Situation.getPLocation());
        Queue = new ArrayList<BFSQueue>();
        Queue.add(new BFSQueue(currSolution,currPoint));
        visitedArray = new ArrayList<Coordinat>();
        visitedArray.add(currPoint);
        showBFS();
    }
    //method pencarian utama
    public void doSearch(){
        /* selama list item belum habis, lakukan :
         * cek queue terdepan, buat cabang yg allowed, masukkan koordinat cabang ke dalam queue beserta jalurnya,
         * majukan currPoint ke queue selanjutnya, cek apakah goal atau bukan, jika ya, kurangi list item, jika list item
         * kosong, berarti pencarian selesai, jika tidak, 
         * ulangi pencarian dengan queue baru dimulai dari titik tersebut (jika truk masih mampu) atau kembali ke P (dengan
         * memanfaatkan jalur yg disimpan) jika truk sudah penuh, dan visitedArray yg baru, jika tidak, ulangi langkah :
         * buat cabang yg allowed, majukan currPoint ke queue selanjutnya...
         *
         */
        while(currListItem.isEmpty() == false){
            for(int i=0;i<=3;i++){
                if(isAllowed(i)){
                    System.out.println("move(" + i + ") ALLOWED");
                    currSolution = new Track(currSolution.addJalur(i).getJalur());
                    currPoint = new Coordinat(currPoint.move(i));
                    Queue.add(new BFSQueue(currSolution,currPoint));
                }
            }
            //cek mesin dan vendor
            if(Situation.getMap()[currPoint.x][currPoint.y] != '~'){
                if(Situation.getMap()[currPoint.x][currPoint.y] == 'P' && currListItem.get(0) == -999){
                    currListItem.remove(0);
                    //bersihkan visitedArray & Queue
                    visitedArray.clear();
                    Queue.clear();
                }
                else{
                    for(int i=0;i<=Situation.getListVendor().size()-1;i++){
                        if(Situation.getMap()[currPoint.x][currPoint.y] == Situation.getListVendor().get(i).getName()){
                            if(Situation.getListVendor().get(i).getlistMesin().contains(currListItem.get(0))){
                                //mendapatkan barang yang dimaksud
                                currListItem.remove(0);
                                //kembali ke P
                                for(int j=currSolution.getJalur().length()-1;j>=0;j--){
                                    Track tempSolution = new Track();
                                    int reverse = currSolution.getJalur().charAt(j) - 48 + 2;
                                    int revres = reverse%3;
                                    tempSolution.addJalur(revres);
                                }
                                //bersihkan visitedArray & Queue
                                visitedArray.clear();
                                Queue.clear();
                                Queue.add(new BFSQueue(currSolution,currPoint));
                            }
                        }
                    }
                }
            }
            visitedArray.add(currPoint);
            //remove queue yg sudah dieksekusi
            Queue.remove(0);
            //ganti current point dan solution ke queue terdepan setelah penghapusan
            currPoint = new Coordinat(Queue.get(0).Coordinat);
            currSolution = Queue.get(0).Trek;
            showBFS();
        }
    }
    public boolean isAllowed(int i){
        //batasan-batasan, jika lewat dimensi map atau menabrak # atau sudah visited
        if(currPoint.move(i).x < Situation.getSizeX()
                && currPoint.move(i).x >= 0 && currPoint.move(i).y < Situation.getSizeY() && currPoint.move(i).y >= 0){
            if(Situation.getMap()[currPoint.move(i).x][currPoint.move(i).y] == '#' || visitedArray.contains(currPoint.move(i))){
                System.out.println("move(" + i + ")NOT ALLOWED pager atau visited");
                return false;
            }
            else{
                return true;
            }
        }
        else{ //di luar dimensi map
            System.out.println("move(" + i + ")NOT ALLOWED di luar dimensi");
            return false;
        }
    }
    //method untuk mengembalikan hasil
    public ArrayList<Coordinat> getSolution(){
        return CoordinatSolution;
    }
    public void showBFS(){
        System.out.print("currSolution : ");
        currSolution.showTrack();
        System.out.print("currPoint : ");
        currPoint.showCoordinat();
        System.out.println();
    }
    //method untuk menyusun CoordinatResult dari posisi awal P dan currSolution yang terbentuk
    public void createCoordinatResult(){
        
    }
}
